package com.jh3502.helper.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.ContactsContract;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.text.InputType;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.LazyHeaders;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.google.gson.Gson;
import com.jh3502.helper.Jh3502HelperApplication;
import com.jh3502.helper.R;
import com.jh3502.helper.base.BaseActivity;
import com.jh3502.helper.function.bluetooth.BlueToothCheckCode;
import com.jh3502.helper.function.person.personlist.PersonListBean;
import com.jh3502.helper.net.ApiConstants;
import com.jh3502.helper.utils.bluetooth.NotifyDataEvent;
import com.vise.baseble.model.BluetoothLeDevice;
import com.vise.baseble.utils.HexUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;


/**
 * 一般工具类
 * Created by harisucici on 2017/6/13.
 */

public class Utils {
    private static Utils utils;
    // 防止双击
    private long lastClickTime;

    public static synchronized Utils getInstance() {
        if (utils == null) {
            utils = new Utils();
        }
        return utils;
    }

    public String encode(String s) {
        String result = "";
        try {
            result = URLEncoder.encode(s, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    public String getNowTime() {
        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//    java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat("yyyy年MM月dd日 HH:mm");
//    java.text.SimpleDateFormat formater = new java.text.SimpleDateFormat("HH:mm");
        return formater.format(new Date());
    }

    public String getNowTimeToRecord() {
        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        return formater.format(new Date());
    }

    public String timeToDate(long time) {
        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formater.format(time);
    }

    public String timeToDate(String time) {
        try {
            Long aLong = Long.valueOf(time);
            SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return formater.format(aLong);
        } catch (NumberFormatException ignored) {
            return time;
        }
    }

    // 获得几天之前或者几天之后的日期
    public String getOtherDay(int day) {
        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
        Calendar mCalendar = Calendar.getInstance();
        mCalendar.add(Calendar.DATE, day);
        return formater.format(mCalendar.getTime());
    }

    @NonNull
    public String[] timeToDate1(String time) {
        String[] timeArray = new String[2];
        try {
            Long aLong = Long.valueOf(time);
            SimpleDateFormat formatDay = new SimpleDateFormat("MM-dd");
            SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
            timeArray[0] = formatDay.format(aLong);
            timeArray[1] = formatTime.format(aLong);
            return timeArray;
        } catch (NumberFormatException ignored) {
            timeArray[0] = time;
            return timeArray;
        }
    }

    public String dateToTime(String date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        String time = "";
        try {
            Date d = dateFormat.parse(date);
            time = timeFormat.format(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    public String getStampToTime(long stamp) {
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return timeFormat.format(new Date(stamp));
    }

    /**
     * 格式化时间（输出类似于 刚刚, 4分钟前, 一小时前, 昨天这样的时间）
     *
     * @param time 需要格式化的时间 如"2014-07-14 19:01:45"
     * @return time为null，或者时间格式不匹配，输出空字符""
     */
    public String formatDisplayTime(long time) {
        String display = "";
        int tMin = 60 * 1000;
        int tHour = 60 * tMin;
        int tDay = 24 * tHour;

        if (time != 0) {
            String pattern = "yyyy-MM-dd HH:mm:ss";
            try {
                Date tDate = new SimpleDateFormat(pattern).parse(timeToDate(time));
                Date today = new Date();
                SimpleDateFormat thisYearDf = new SimpleDateFormat("yyyy");
                SimpleDateFormat todayDf = new SimpleDateFormat("yyyy-MM-dd");
                Date thisYear = new Date(thisYearDf.parse(thisYearDf.format(today)).getTime());
                Date yesterday = new Date(todayDf.parse(todayDf.format(today)).getTime());
                Date beforeYes = new Date(yesterday.getTime() - tDay);
                if (tDate != null) {
                    @SuppressWarnings("unused")
                    SimpleDateFormat halfDf = new SimpleDateFormat("MM月dd日");
                    long dTime = today.getTime() - tDate.getTime();
                    if (tDate.before(thisYear)) {
                        display = new SimpleDateFormat("yyyy年MM月dd日").format(tDate);
                    } else {
                        if (dTime < tMin) {
                            display = "刚刚";
                        } else if (dTime < tHour) {
                            display = (int) Math.ceil(dTime / tMin) + "分钟前";
                        } else if (dTime < tDay && tDate.after(yesterday)) {
                            display = (int) Math.ceil(dTime / tHour) + "小时前";
                        } else if (tDate.after(beforeYes) && tDate.before(yesterday)) {
                            display = "昨天 " + new SimpleDateFormat("HH:mm").format(tDate);
                        } else {
                            display = timeToDate(tDate.getTime());
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return display;
    }

    /**
     * 打开扬声器
     */
    public void openSpeaker(@NonNull Context context) {
        String m = Build.MANUFACTURER;
        try {
            AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            if (!m.toLowerCase().contains("xiaomi")) {
                audioManager.setMode(AudioManager.ROUTE_SPEAKER);
            }
            int currVolume = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
            if (!audioManager.isSpeakerphoneOn()) {
//        setSpeakerphoneOn() only work when audio mode set to MODE_IN_CALL.
                audioManager.setMode(AudioManager.MODE_IN_CALL);
                audioManager.setSpeakerphoneOn(true);
                audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
                        audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
                        AudioManager.STREAM_VOICE_CALL);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭扬声器
     */
    public void closeSpeaker(@NonNull Context context) {
        try {
            AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            if (audioManager != null) {
                if (audioManager.isSpeakerphoneOn()) {
                    audioManager.setSpeakerphoneOn(false);
                    audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 0,
                            AudioManager.STREAM_VOICE_CALL);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 听筒静音
     */
    public void closeListener(@NonNull Context context) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        if (audioManager != null) {
            audioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, 0, AudioManager.FLAG_SHOW_UI);
        }
    }


    /**
     * 图片加载工具Glide加入token
     */
    public void showUrlImage(@NonNull Context context, String url, @NonNull ImageView imageView) {
        RequestOptions options = new RequestOptions()
                .placeholder(R.mipmap.ic_launcher);
        Glide.with(context)
                .load(new GlideUrl(url
                        , new LazyHeaders
                        .Builder()
                        .addHeader(Constant.APP_TOKEN, SpHelper.getInstance().getToken())
                        .build()))
                .apply(options)
                .into(imageView);
    }

    /**
     * 加载本地视频缩略图
     *
     * @param context
     * @param videoId
     * @param imageView
     */
    public void showVideoThumbnail(@NonNull Context context, String videoId, @NonNull ImageView imageView) {
        Glide.with(context)
                .load(Uri.fromFile(new File(SdCard.getInstance().getVideo(), videoId + ".mp4")))
                .into(imageView);
    }

    //加载圆角图片
//  public void loadRoundImage(Context context, String url, final ImageView imageView) {
//    Glide.with(context)
//        .load(new GlideUrl(url,
//            new LazyHeaders
//                .Builder()
//                .addHeader(Constant.APP_TOKEN, SpHelper.getInstance().getToken())
//                .build()))
//        .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(10, 0)))
//        .into(imageView);
//  }


    //加载圆形图片
//  public void loadCirclePic(final Context context, String url, final ImageView imageView) {
//    Glide.with(context)
//        .load(url)
//        .asBitmap()
//        .placeholder(placeholder)
//        .error(placeholder)
//        .diskCacheStrategy(DiskCacheStrategy.ALL) //设置缓存
//        .into(new BitmapImageViewTarget(imageView) {
//          @Override
//          protected void setResource(Bitmap resource) {
//            RoundedBitmapDrawable circularBitmapDrawable =
//                RoundedBitmapDrawableFactory.create(context.getResources(), resource);
//            circularBitmapDrawable.setCircular(true);
//            imageView.setImageDrawable(circularBitmapDrawable);
//          }
//        });
//
//  }

    /**
     * 图片加载工具Glide加入token
     */
    public void showUrlImage(@NonNull Fragment fragment, String url, @NonNull final ImageView imageView) {
        Glide.with(fragment)
                .load(new GlideUrl(url
                        , new LazyHeaders
                        .Builder()
                        .addHeader(Constant.APP_TOKEN, SpHelper.getInstance().getToken())
                        .build()))
//        .into(imageView);
                .into(new SimpleTarget<Drawable>() {
                    @Override
                    public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
                        imageView.setImageDrawable(resource);
                    }
                });
    }

    /**
     * netType = 2 为移动网络
     * netType = 1 为WiFi网络
     * nteType = 0 为无网络
     *
     * @param context
     * @return
     */
    public int getNetworkType(@NonNull Context context) {
        int netType = 0;
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo == null) {
            return netType;
        }
        int nType = networkInfo.getType();
        if (nType == ConnectivityManager.TYPE_MOBILE) {
            netType = 2;
        } else if (nType == ConnectivityManager.TYPE_WIFI) {
            netType = 1;
        }
        return netType;
    }

    /**
     * 获取屏幕的宽度px
     *
     * @param context 上下文
     * @return 屏幕宽px
     */
    public int getScreenWidth(@NonNull Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.widthPixels;
    }

    /**
     * 获取屏幕的高度px
     *
     * @param context 上下文
     * @return 屏幕高px
     */
    public int getScreenHeight(@NonNull Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.heightPixels;
    }

    /**
     * convert dp to its equivalent px
     * <p>
     * 将dp转换为与之相等的px
     */
    public int dp2px(@NonNull Context context, float dipValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    /**
     * 从38.024059,114.434081形式的坐标中取出内容
     * @param latlng
     * @return
     */
//  public LatLng getLatLngFromString(String latlng){
//    String[] latlong = latlng.split(",");
//    double latitude = Double.parseDouble(latlong[1]);
//    double longitude = Double.parseDouble(latlong[0]);
//    return new LatLng(latitude, longitude);
//  }
//
//  public int checkFileType(String path) {
//    if (path.contains(".mp4") || path.contains(".avi") || path.contains(".3gp")) {
//      return Constant.TYPE_VIDEO;
//    }
//    if (path.contains(".mp3") || path.contains(".aac") || path.contains(".amr")) {
//      return Constant.TYPE_VOICE;
//    }
//    if (path.contains(".png") || path.contains(".jpg")) {
//      return Constant.TYPE_IMAGE;
//    }
//    return -1;
//  }
//
//  public ReciveMessageEntity getReceiveMsgInfo(String text){
//    if (text.contains(Constant.SEND_IMAGE_MSG_TAG_START)){
//      return new ReciveMessageEntity(text
//          .replace(Constant.SEND_IMAGE_MSG_TAG_START, "")
//          .replace(Constant.SEND_IMAGE_MSG_TAG_END, "")
//          , Constant.TYPE_IMAGE);
//    }else if (text.contains(Constant.SEND_VIDEO_MSG_TAG_START)){
//      return new ReciveMessageEntity(text
//          .replace(Constant.SEND_VIDEO_MSG_TAG_START, "")
//          .replace(Constant.SEND_VIDEO_MSG_TAG_END, "")
//          , Constant.TYPE_VIDEO);
//    }else if (text.contains(Constant.SEND_VOICE_MSG_TAG_START)){
//      return new ReciveMessageEntity(text
//          .replace(Constant.SEND_VOICE_MSG_TAG_START, "")
//          .replace(Constant.SEND_VOICE_MSG_TAG_END, "")
//          , Constant.TYPE_VOICE);
//    }else {
//      return new ReciveMessageEntity("", -1);
//    }
//  }

    /**
     * 获取location中的具体地址
     *
     * @param locationString
     * @return
     */
    @NonNull
    public String getLocationAddress(@NonNull String locationString) {
        int begin = locationString.indexOf("#address=");
        int end = locationString.indexOf("#country=");
        String address = "";
        if (begin > 0 && end > 0) {
            address = locationString.substring(begin + 8, end - 1);
        }
        return address;
    }

    /**
     * 获取activity的view
     */
    public View getContentView(@NonNull Activity context) {
        return ((ViewGroup) context.findViewById(android.R.id.content)).getChildAt(0);
    }

    /**
     * 验证手机号码
     * 现有手机号段:
     * 移动：139  138  137  136  135  134  147  150  151  152  157  158  159  178 182  183  184  187  188
     * 联通：130  131  132  155  156  185  186  145  176
     * 电信：133  153  177  173  180  181  189
     * 虚拟运营商：
     * 170 171
     */
    public boolean checkMobileNumber(@NonNull String mobileNumber) {
        boolean flag;
        try {
            Pattern regex = compile("^((13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8})$");
            Matcher matcher = regex.matcher(mobileNumber);
            flag = matcher.matches();
        } catch (Exception ignored) {
            flag = false;
        }
        return flag;
    }

    /**
     * 检查系统是否有downloadmanager
     *
     * @param context
     * @return
     */
    public boolean canDownloadState(@NonNull Context context) {
        try {
            int state = context.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
            if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 开启新的activity并传值
     *
     * @param fromActivity
     * @param toActivity
     */
    public void startActivity(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity) {
        startActivity(fromActivity, toActivity, null);
    }

    public void startActivity(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity, boolean finishThisActivity) {
        startActivity(fromActivity, toActivity, null);
        if (finishThisActivity) {
            fromActivity.finish();
        }
    }

    public void startActivity(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity,
                              @Nullable Bundle bundle) {
        startActivity(fromActivity, toActivity, bundle, false);
    }

    public void startActivity(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity,
                              @Nullable Bundle bundle, boolean finishThisActivity) {
        Intent intent = new Intent(fromActivity, toActivity);
        if (null != bundle) {
            bundle.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(bundle);
        } else {
            Bundle b = new Bundle();
            b.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(b);
        }
        fromActivity.startActivity(intent);
        if (finishThisActivity) {
            fromActivity.finish();
        }
    }

    public void startActivityForResult(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity, int requestCode) {
        startActivityForResult(fromActivity, toActivity, null, requestCode);
    }

    public void startActivityForResult(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity,
                                       @Nullable Bundle bundle, int requestCode) {
        startActivityForResult(fromActivity, toActivity, bundle, false, requestCode);
    }

    public void startActivityForResult(@NonNull Activity fromActivity, Class<? extends BaseActivity> toActivity,
                                       @Nullable Bundle bundle, boolean finishThisActivity, int requestCode) {
        Intent intent = new Intent(fromActivity, toActivity);
        if (null != bundle) {
            bundle.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(bundle);
        } else {
            Bundle b = new Bundle();
            b.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(b);
        }
        fromActivity.startActivityForResult(intent, requestCode);
        if (finishThisActivity) {
            fromActivity.finish();
        }
    }

    /**
     * 从通讯录选择联系人
     *
     * @param activity
     * @param uri
     * @return
     */
    @Nullable
    public String[] getPhoneContacts(@NonNull Activity activity, @NonNull Uri uri) {
        String[] contact = new String[2];
        ContentResolver cr = activity.getContentResolver();
        Cursor cursor = cr.query(uri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            //取得联系人姓名
            int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
            contact[0] = cursor.getString(nameFieldColumnIndex);
            //取得电话号码
            String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
            if (phone != null) {
                phone.moveToFirst();
                contact[1] = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
            phone.close();
            cursor.close();
        } else {
            return null;
        }
        return contact;
    }

    /****
     * 动态设置listview高度
     ****/
    public void setListViewHeightBasedOnChildren(@NonNull ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;
        }
        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

    /**
     * 设定edittext是否显示密码内容
     *
     * @param editText
     * @param isHide
     */
    public void setEditTextPasswordType(@NonNull EditText editText, boolean isHide) {
        editText.setInputType(isHide ?
                InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :
                InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
    }

    /**
     * 获取版本号
     *
     * @return
     */

    @NonNull
    public String getVersionCode() {
        PackageInfo info = null;
        Context context = Jh3502HelperApplication.getAppContext();
        try {
            info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return info.versionCode + "";
    }

    @NonNull
    public String getVersionName() {
        PackageInfo info = null;
        Context context = Jh3502HelperApplication.getAppContext();
        try {
            info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return info.versionName + "";
    }

    @Nullable
    public String listToString(@Nullable List<String> list) {
        if (list == null) {
            return null;
        }
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (String string : list) {
            if (first) {
                first = false;
            } else {
                result.append(", ");
            }
            result.append(string);
        }
        return result.toString();
    }
//  public boolean isBadJson(String json) {
//    return !isGoodJson(json);
//  }
//
//  public boolean isGoodJson(String json) {
//    if (StringUtils.isBlank(json)) {
//      return false;
//    }
//    try {
//      new JsonParser().parse(json);
//      return true;
//    } catch (JsonParseException e) {
//
//      return false;
//    }
//  }

    public int checkFileType(@NonNull String path) {
        if (path.contains(".mp4") || path.contains(".avi") || path.contains(".3gp")) {
            return Constant.TYPE_VIDEO;
        }
        if (path.contains(".mp3") || path.contains(".aac") || path.contains(".amr")) {
            return Constant.TYPE_VOICE;
        }
        if (path.contains(".png") || path.contains(".jpg")) {
            return Constant.TYPE_IMAGE;
        }
        return -1;
    }

    public void openLocalVideo(@NonNull Context context, @NonNull String videoPath) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri data = FileProvider.getUriForFile(context, context.getPackageName() + ".FileProvider", new File(videoPath));
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setDataAndType(data, "video/mp4");
        context.startActivity(intent);
    }

    public boolean isNull(@Nullable Object object) {
        return object == null || "".equals(object.toString().trim());
    }

    /**
     * 调用拨号界面
     *
     * @param phone 电话号码
     */
    public void callPhone(@NonNull Context context, String phone) {
        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    @Nullable
    public String getChatHistoryFileUrl(int type, @NonNull String text) {
        switch (type) {
            case ConstantUtil.TYPE_IMAGE:
                return ApiConstants.getUploadFileUrl(text.replace(ConstantUtil.SEND_IMAGE_MSG_TAG_START, ""))
                        .replace(ConstantUtil.SEND_IMAGE_MSG_TAG_END, "");
//        return ConstantUrl.FILE+text.replace(ConstantUtil.SEND_IMAGE_MSG_TAG_START, "")
//            .replace(ConstantUtil.SEND_IMAGE_MSG_TAG_END, "");

            case ConstantUtil.TYPE_VIDEO:
                return ApiConstants.getUploadFileUrl(text.replace(ConstantUtil.SEND_VIDEO_MSG_TAG_START, ""))
                        .replace(ConstantUtil.SEND_VIDEO_MSG_TAG_END, "");
//      return ConstantUrl.FILE+text.replace(ConstantUtil.SEND_VIDEO_MSG_TAG_START, "")
//            .replace(ConstantUtil.SEND_VIDEO_MSG_TAG_END, "");

            case ConstantUtil.TYPE_VOICE:
                return ApiConstants.getUploadFileUrl(text.replace(ConstantUtil.SEND_VOICE_MSG_TAG_START, ""))
                        .replace(ConstantUtil.SEND_VOICE_MSG_TAG_END, "");

//      return ConstantUrl.FILE+text.replace(ConstantUtil.SEND_VOICE_MSG_TAG_START, "")
//            .replace(ConstantUtil.SEND_VOICE_MSG_TAG_END, "");

            default:
                break;
        }
        return null;
    }

    public int getChatHistoryType(@NonNull String text) {
        if (isNull(text)) {
            return -1;
        }
        if (text.contains(ConstantUtil.SEND_IMAGE_MSG_TAG_START)) {
            return ConstantUtil.TYPE_IMAGE;
        } else if (text.contains(ConstantUtil.SEND_VIDEO_MSG_TAG_START)) {
            return ConstantUtil.TYPE_VIDEO;
        } else if (text.contains(ConstantUtil.SEND_VOICE_MSG_TAG_START)) {
            return ConstantUtil.TYPE_VOICE;
        } else {
            return ConstantUtil.TYPE_TEXT;
        }
    }

    //将px值转换为sp值，保证文字大小不变
    public int px2sp(@NonNull Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    //将sp值转换为px值，保证文字大小不变
    public int sp2px(@NonNull Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    //根据手机的分辨率从 dp 的单位 转成为 px(像素)
    public int dip2px(@NonNull Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    //根据手机的分辨率从 px(像素) 的单位 转成为 dp
    public int px2dip(@NonNull Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    public String numberFormat(float f, int m) {

        return String.format("%." + m + "f", f);
    }

    public float numberFormatFloat(float f, int m) {
        String strfloat = numberFormat(f, m);
        return Float.parseFloat(strfloat);
    }

    //检查null
    @Nullable
    public String checkNullEmpty(@Nullable String string) {
        String s = (string == null || "null".equals(string) || "[]".equals(string) || string.length() == 0) ? "" : string;
        return s;
    }

    //检查null
    @Nullable
    public String checkNullUnKnow(@Nullable String string) {
        String s = (string == null || "null".equals(string) || string.length() == 0) ? "未知" : string;
        return s;
    }

    //检查null
    public int checkNullZero(@Nullable String string) {
        int n = (string == null || "null".equals(string) || string.length() == 0) ? 0 : Integer.parseInt(string);
        return n;
    }

    // JsonArrayString 转ArrayList
    @NonNull
    public ArrayList<Map<String, Object>> jsa2list(String s) {
        ArrayList<Map<String, Object>> dataList = new ArrayList<>();
        JSONArray jsonArray;
        try {
            jsonArray = new JSONArray(s);
            for (int i = 0; i < jsonArray.length(); i++) {
                dataList.add(jso2map(jsonArray.get(i).toString()));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return dataList;
    }

    @NonNull
    public ArrayList<String> jsa2list1(String s) {
        ArrayList<String> dataList = new ArrayList<>();
        JSONArray jsonArray;
        try {
            jsonArray = new JSONArray(s);
            for (int i = 0; i < jsonArray.length(); i++) {
                dataList.add(jsonArray.get(i).toString());
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return dataList;
    }

    //JsonObjectString转Map
    @Nullable
    public Map<String, Object> jso2map(@Nullable String s) {
        JSONObject jsonObjTemp;
        Map<String, Object> map = new HashMap<>(2);
        if (s == null) {
            return null;
        }
        try {
            jsonObjTemp = new JSONObject(s);
            Iterator ite = jsonObjTemp.keys();
            while (ite.hasNext()) {
                String key = ite.next().toString();
                String value = jsonObjTemp.get(key).toString();
                map.put(key, value);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return map;
    }

    @Nullable
    public String getMapString(@NonNull Map<String, Object> map, String index) {
        String s = checkNullEmpty((String) map.get(index));
        return checkNullEmpty((String) map.get(index));
    }

    public int getMapInt(@NonNull Map<String, Object> map, String index) {
        return checkNullZero((String) map.get(index));
    }

    //base64 互转
    public Bitmap base642Bitmap(String s) {
        byte[] bytes = Base64.decode(s, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    //base64 互转
    public String bitmap2Base64(String uri) {
        Bitmap bit = BitmapFactory.decodeFile(uri);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //参数100表示不压缩
        bit.compress(Bitmap.CompressFormat.PNG, 50, bos);
        byte[] bytes = bos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }

    /**
     * 提供精确的加法运算。
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    public double sub(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
     * 定精度，以后的数字四舍五入。
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public double div(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public double round(String v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(v);
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    // 取得电子尺的尺寸
    public double getRuler(@NonNull NotifyDataEvent event, @NonNull BluetoothLeDevice mDeviceTemp) {
        byte[] arrayOfByte = event.getData();
        String[] name = mDeviceTemp.getName().split(" ");
        Log.e("3502", HexUtil.encodeHexStr(arrayOfByte));
        if ("eType".equals(name[0])) {
            if (arrayOfByte[0] != 86) {
                long l = BlueToothCheckCode.check(arrayOfByte);
                return div(String.valueOf(l), 10 + "", 2);
            }

        } else if ("Gymate_T".equals(name[0])) {
            String code = arrayOfByte[8] + "";//ac00 0704 0000 20 01 0200 0000 2eff 3.2
            if ("2".equals(code)) {
                String s =
                        HexUtil.encodeHexStr(arrayOfByte).substring(10, 12) + HexUtil.encodeHexStr(arrayOfByte).substring(12, 14);
                if ("14".equals(s)) {

                }
                return BlueToothCheckCode.check(s);
            }

        }
        return -1;
    }

    //从protobuf转json
//  Message someProto =SomeProto.getDefaultInstance();
//  String jsonFormat =JsonFormat.printToString(someProto);
    //  从json转protobuf
//  Message.Builder builder =SomeProto.newBuilder();
//  String jsonFormat = _load json document from a source_;
//  JsonFormat.merge(jsonFormat, builder);
// 专为Android4.4设计的从Uri获取文件绝对路径，以前的方法已不好使
    @Nullable
    @SuppressLint("NewApi")
    public String getPath(@NonNull final Context context, @NonNull final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (UploadHelper.getInstance().isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            // DownloadsProvider
            else if (UploadHelper.getInstance().isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (UploadHelper.getInstance().isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{split[1]};

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        return null;
    }

    @Nullable
    public String getDataColumn(@NonNull Context context, @NonNull Uri uri, String selection,
                                String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {column};

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(columnIndex);
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }

    public boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        long timeD = time - lastClickTime;
        if (0 < timeD && timeD < Constant.DOUBLE_CLICK) {
            return true;
        }
        lastClickTime = time;
        return false;
    }


    @NonNull
    public List<PersonListBean> map2Person(String s) {
        List<PersonListBean> personList = new ArrayList<>(2);
        Map<String, Object> orgMap = jso2map(s);
        Set<String> orgkey = orgMap.keySet();
        for (String keyOrg : orgkey) {
            Map<String, Object> depMap = jso2map((String) orgMap.get(keyOrg));
            Set<String> depkey = depMap.keySet();
            for (String keyDep : depkey) {
                ArrayList<String> personListMap = jsa2list1((String) depMap.get(keyDep));
                for (String personString : personListMap) {
                    personList.add(new Gson().fromJson(personString, PersonListBean.class));
                }
            }
        }
        return personList;
    }

    @NonNull
    public Map<String, Object> person2Map(@NonNull List<PersonListBean> list) {
        Map<String, Object> orgMap = new HashMap<>(2);
        for (PersonListBean personListBean : list) {
            if (!orgMap.containsKey(personListBean.getOrg())) {
                Map<String, Object> depMap = new HashMap<>(2);
                List<PersonListBean> peresonList = new ArrayList<>(2);
                peresonList.add(personListBean);
                depMap.put(personListBean.getDep(), peresonList);
                orgMap.put(personListBean.getOrg(), depMap);
            } else {
                Map<String, Object> depMap = (Map<String, Object>) orgMap.get(personListBean.getOrg());
                if (!depMap.containsKey(personListBean.getDep())) {
                    List<PersonListBean> peresonList = new ArrayList<>(2);
                    peresonList.add(personListBean);
                    depMap.put(personListBean.getDep(), peresonList);
                } else {
                    List<PersonListBean> peresonList = (List<PersonListBean>) depMap.get(personListBean.getDep());
                    peresonList.add(personListBean);
                }

            }
        }

        return orgMap;
    }
}
